﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static LiWi.Shell;

namespace LiWi
{
  

    public partial class 回原点 : Form
    {
        #region
        public WindowsAdapt adapt = new WindowsAdapt();

        IntPtr _handle { get { return Data.handle; } }
        bool isConnect { get { return Data.handle == (IntPtr)0 ? false : true; } }
        IniAPI INI=new IniAPI();
        string file = AppDomain.CurrentDomain.BaseDirectory+"HomeData.ini";

        static int axisNum = 5;
        static int[] axisList = { 0, 1, 2, 3, 4 };
        bool axisFlag=false;                        //轴运动标志
        
        int _model;                                 //回原模式
        int _goBackModel;                           //限位反找开关:1开启
        int[] _openGo=new int[axisNum];             //回原开关
        int[] _hardFwdIN=new int[axisNum];          //正硬限位IO
        int[] _hardRevIN=new int[axisNum];          //负硬限位IO
        int[] _homeIN=new int[axisNum];             //原点IO
        int[] _waitCT=new int[axisNum];             //反找等待时间
        float[] _pianyi=new float[axisNum];             //偏移距离
        float[] _creep=new float[axisNum];              //爬行速度


        ToolTip toolTip = new ToolTip();


        Thread thGoHome=null;



        #endregion
        public 回原点()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            Control.CheckForIllegalCrossThreadCalls = false;
            readINIvalue();
            adapt.SetForm(this);

            
            toolTip.InitialDelay = 500;//鼠标静止0.5s后显示
            toolTip.ReshowDelay = 500;//再次显示时间
        }



        /// <summary>
        /// 限位反找
        /// </summary>
        public void isGoBack()
        {
            if (_goBackModel==1) _model = Convert.ToInt32(commodel.Text) + 10;
            else _model = Convert.ToInt32(commodel.Text);
        }

        /// <summary>
        /// 保存参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            //创建文件
            if (!File.Exists(file))
            {
                FileStream fs=new FileStream(file, FileMode.Create);
                fs.Close();
            }

            _model=Convert.ToInt32( commodel.Text);             //回原模式
            _goBackModel = chkGoBack.Checked?1:0;               //限位反找开关

            IniAPI.INIWriteValue(file, "回原", "回原模式", _model.ToString());
            IniAPI.INIWriteValue(file, "回原", "限位反找开关", _goBackModel.ToString());

            for (int i = 0; i < axisNum; i++)
            {
                var open_go = "chkopenGo" + i;            //回原开关
                var opengo = this.Controls.Find(open_go, true).FirstOrDefault() as CheckBox;
                _openGo[i] = opengo.Checked ? 1 : 0;

                var hard_fwdin = "comfwdin" + i;                //正硬限位IO
                var hardfwdin = this.Controls.Find(hard_fwdin, true).FirstOrDefault() as ComboBox;
                _hardFwdIN[i] = Convert.ToInt32( hardfwdin.Text);

                var hard_revin = "comrevin" + i;                //负硬限位IO
                var hardrevin = this.Controls.Find(hard_revin, true).FirstOrDefault() as ComboBox;
                _hardRevIN[i] = Convert.ToInt32(hardrevin.Text);

                var home_in = "combhomein" + i;                 //原点IO
                var homein = this.Controls.Find(home_in, true).FirstOrDefault() as ComboBox;
                _homeIN[i] = Convert.ToInt32(homein.Text);

                var wait_CT = "numwaitCT" + i;                 //反找等待时间
                var waitCT = this.Controls.Find(wait_CT, true).FirstOrDefault() as NumericUpDown;
                _waitCT[i] = Convert.ToInt32(waitCT.Text);

                var pian_yi = "numpianyi" + i;                 //偏移距离
                var pianyi = this.Controls.Find(pian_yi, true).FirstOrDefault() as NumericUpDown;
                _pianyi[i] = Convert.ToSingle(pianyi.Text);

                var num_creep = "numcreep" + i;                 //爬行速度
                var numcreep = this.Controls.Find(num_creep, true).FirstOrDefault() as NumericUpDown;
                _creep[i] = Convert.ToSingle(numcreep.Text);


                IniAPI.INIWriteValue(file, $"轴{i}", "回原开关", _openGo[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "正硬限位IO", _hardFwdIN[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "负硬限位IO", _hardRevIN[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "原点IO", _homeIN[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "反找等待时间", _waitCT[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "偏移距离", _pianyi[i].ToString());
                IniAPI.INIWriteValue(file, $"轴{i}", "爬行速度", _creep[i].ToString());
            }
            MessageBox.Show("保存完成");

        }


        /// <summary>
        /// 读取参数
        /// </summary>
        public void readINIvalue()
        {
            if (!File.Exists(file))
            {
                return;
            }
            string model="", goBackModel="";
            string[] openGo = new string[axisNum];
            string[] hardFwdIN = new string[axisNum];
            string[] hardRevIN = new string[axisNum];
            string[] homeIN = new string[axisNum];
            string[] waitct = new string[axisNum];
            string[] pianYi = new string[axisNum];
            string[] creep = new string[axisNum];
            model= IniAPI.INIGetStringValue(file, "回原", "回原模式", "0");
            goBackModel = IniAPI.INIGetStringValue(file, "回原", "限位反找开关", "0");
            _model = Convert.ToInt32( model);            
            _goBackModel = Convert.ToInt32( goBackModel );
            isGoBack();
            commodel.Text = model;
            chkGoBack.Checked = _goBackModel==1?true:false;

            for (int i = 0; i < axisNum; i++)
            {
                openGo[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "回原开关", "1");
                hardFwdIN[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "正硬限位IO", "1");
                hardRevIN[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "负硬限位IO", "1");
                homeIN[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "原点IO", "1");

                waitct[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "反找等待时间", "1000");
                pianYi[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "偏移距离", "100");
                creep[i] = IniAPI.INIGetStringValue(file, $"轴{i}", "爬行速度", "50");

                _openGo[i]=Convert.ToInt32( openGo[i]);
                _hardFwdIN[i]=Convert.ToInt32( hardFwdIN[i]);
                _hardRevIN[i]= Convert.ToInt32( hardRevIN[i]);
                _homeIN[i] = Convert.ToInt32( homeIN[i]);
                _waitCT[i] = Convert.ToInt32(waitct[i]);
                _pianyi[i] = Convert.ToSingle(pianYi[i]);
                _creep[i] = Convert.ToSingle(creep[i]);

                var open_go = "chkopenGo" + i;            //回原开关
                var opengo = this.Controls.Find(open_go, true).FirstOrDefault() as CheckBox;
                opengo.Checked = _openGo[i] ==1 ? true : false; 

                var hard_fwdin = "comfwdin" + i;                //正硬限位IO
                var hardfwdin = this.Controls.Find(hard_fwdin, true).FirstOrDefault() as ComboBox;
                hardfwdin.Text=_hardFwdIN[i].ToString();

                var hard_revin = "comrevin" + i;                //负硬限位IO
                var hardrevin = this.Controls.Find(hard_revin, true).FirstOrDefault() as ComboBox;
                hardrevin.Text= _hardRevIN[i].ToString();

                var home_in = "combhomein" + i;                 //原点IO
                var homein = this.Controls.Find(home_in, true).FirstOrDefault() as ComboBox;
                homein.Text= _homeIN[i].ToString();

                var wait_CT = "numwaitCT" + i;                 //反找等待时间
                var waitCT = this.Controls.Find(wait_CT, true).FirstOrDefault() as NumericUpDown;
                waitCT.Text = _waitCT[i].ToString();

                var pian_yi = "numpianyi" + i;                 //偏移距离
                var pianyi = this.Controls.Find(pian_yi, true).FirstOrDefault() as NumericUpDown;
                pianyi.Text=_pianyi[i].ToString();

                var num_creep = "numcreep" + i;                 //爬行速度
                var numcreep = this.Controls.Find(num_creep, true).FirstOrDefault() as NumericUpDown;
                numcreep.Text = _creep[i].ToString();
            }
        }

        private void Btnstop_Click(object sender, EventArgs e)
        {
            if (axisFlag)
            {
                foreach (var item in axisList)
                {
                    PMC_Rapidstop(_handle, 3);
                }
                btngohome.Enabled = true;
                btngohome.Text = "回原";
                axisFlag = false;
                Data._pause = false;
            }
        }

        private void Btnzero_Click(object sender, EventArgs e)
        {
            foreach (var item in axisList)
            {
                PMC_SetDpos(_handle, item, 0);
            }
        }

        /// <summary>
        /// 轴位置读取
        /// </summary>
        /// <returns></returns>
        

        private void btngohome_Click(object sender, EventArgs e)
        {
            PMC_Rapidstop(_handle, 3);
            if (isConnect) goHome();
            else MessageBox.Show("请先连接控制器");
        }

        public async void goHome()
        {
            try
            {
                _model = Convert.ToInt32(commodel.Text);             //回原模式                
                _goBackModel = chkGoBack.Checked ? 1 : 0;               //限位反找开关
                isGoBack();
                for (int i = 0; i < axisNum; i++)
                {

                    
                    var open_go = "chkopenGo" + i;            //回原开关
                    var opengo = this.Controls.Find(open_go, true).FirstOrDefault() as CheckBox;
                    _openGo[i] = opengo.Checked ? 1 : 0;
                    if (_openGo[i]==1)
                    {
                        int enable = 0;
                        PMC_GetAxisEnable(_handle, i, ref enable);
                        if (enable == 0)
                        {
                            MessageBox.Show("有需要回原的轴未使能，请回连接处使能！！！");
                            return;
                        }
                    }

                    var hard_fwdin = "comfwdin" + i;                //正硬限位IO
                    var hardfwdin = this.Controls.Find(hard_fwdin, true).FirstOrDefault() as ComboBox;
                    _hardFwdIN[i] = Convert.ToInt32(hardfwdin.Text);

                    var hard_revin = "comrevin" + i;                //负硬限位IO
                    var hardrevin = this.Controls.Find(hard_revin, true).FirstOrDefault() as ComboBox;
                    _hardRevIN[i] = Convert.ToInt32(hardrevin.Text);

                    var home_in = "combhomein" + i;                 //原点IO
                    var homein = this.Controls.Find(home_in, true).FirstOrDefault() as ComboBox;
                    _homeIN[i] = Convert.ToInt32(homein.Text);

                    var wait_CT = "numwaitCT" + i;                 //反找等待时间
                    var waitCT = this.Controls.Find(wait_CT, true).FirstOrDefault() as NumericUpDown;
                    _waitCT[i] = Convert.ToInt32(waitCT.Text);

                    var pian_yi = "numpianyi" + i;                 //偏移距离
                    var pianyi = this.Controls.Find(pian_yi, true).FirstOrDefault() as NumericUpDown;
                    _pianyi[i] = Convert.ToSingle(pianyi.Text);

                    var num_creep = "numcreep" + i;                 //爬行速度
                    var numcreep = this.Controls.Find(num_creep, true).FirstOrDefault() as NumericUpDown;
                    _creep[i] = Convert.ToSingle(numcreep.Text);
                }

                axisFlag = true;
                btngohome.Enabled = false;
                btngohome.Text = "回原中";

                await Task.Run(() =>
                {
                    //判断缓冲剩余量:如果缓冲小于20等待一下               
                    while (Data.ReMainBuffer(axisList) <= 20)
                    {
                        Thread.Sleep(200);
                    }

                    for (int i = 0; i < axisNum; i++)
                    {
                        if (_openGo[i] == 1)
                        {
                            //设置限位
                            PMC_SetFwdIn(_handle, i, _hardFwdIN[i]);
                            PMC_SetRevIn(_handle, i, _hardRevIN[i]);
                            //设置反找等待时间
                            PMC_SetHomeWait(_handle, i, _waitCT[i]);
                            //设置偏移距离
                            //PMC_BusCmd_SetDatumOffpos(_handle, i, _pianyi[i]);
                            //设置爬行速度
                            PMC_SetCreep(_handle, i, _creep[i]);
                            //设置零点信号
                            PMC_SetDatumIn(_handle, i, _homeIN[i]);

                            //单轴回原
                            PMC_Single_Datum(_handle, i, _model);

                            //ret = LiWi.Shell.PMC_SetInvertIn(_handle, _homeIN[i], 1); // 设置输入口 0 电平反转
                            ////System.Threading.Thread.Sleep(2000); // 再过 2000 毫秒原点信号关闭
                            //ret = LiWi.Shell.PMC_SetInvertIn(_handle, _homeIN[i], 0); //关闭输入口 0 电平反转
                        }
                    }
                });
                Thread thsport = new Thread(() =>
                {
                    foreach (var item in axisList)
                    {
                        var a = 0;
                        PMC_GetIfIdle(_handle, item, ref a);
                        while (a == 0)
                        {
                            PMC_GetIfIdle(_handle, item, ref a);
                            Thread.Sleep(50);
                        }
                    }
                    axisFlag = false;
                    btngohome.Enabled = true;
                    btngohome.Text = "回原";


                }
                );
                thsport.Start();




            }
            catch (Exception e)
            {
                btngohome.Enabled = true;
                btngohome.Text = "回原";
                axisFlag = false;
                MessageBox.Show(e.ToString());
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //string _ip = "192.168.1.11";
            //int ret = PMC_OpenEth(_ip, ref _handle);
            //if (ret == 0)
            //{
            //    isConnect = true;
            //    MessageBox.Show("连接成功");
            //    getPos();

            //}
        }

        
        
        private void linkLabel1_MouseHover(object sender, EventArgs e)
        {
            toolTip.SetToolTip(linkLabel1, 
                "模式0：清除所有轴的错误状态(清除AXISSTATUS的找原点中状态)\r\n" +
                "模式1：轴以爬行速度往正方向回原\r\n" +
                "模式2：轴以爬行速度往负方向回原\r\n" +
                "模式3：轴以速度正常速度正方向移动，碰到原点然后以爬行速度反向运动直至离开原点\r\n" +
                "模式4：轴以速度正常速度反方向移动，碰到原点然后以爬行速度正向运动直至离开原点\r\n" +
                "模式5：轴以正常速度正方向移动，直至碰到原点IO，然后以爬行速度离开原点，直至碰到负限位\r\n" +
                "模式6：轴以正常速度反方向移动，直至碰到原点IO，然后以爬行速度离开原点，直至碰到正限位\r\n" +
                "模式8：轴以正常速度正方向移动，直至碰到原点IO\r\n" +
                "模式9：轴以正常速度反方向移动，直至碰到原点IO\r\n" +
                "模式21：使用Ethercat驱动器回零功能，此时模式2有效");
        }
    }
}
